﻿#ifndef LIB_INCLUDE_UNITS_C_H_
#define LIB_INCLUDE_UNITS_C_H_

#pragma once

#ifdef __cplusplus
extern "C" {
#endif

/**
 * @brief 定义导出宏，用于控制符号的可见性
 *
 * 根据平台和编译选项定义 UNITS_API 宏，用于标记需要导出或导入的函数和变量
 */
#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(UNITS_STATIC_DEFINE)
#define UNITS_API
#elif defined(UNITS_BUILDING_DLL)
#define UNITS_API __declspec(dllexport)
#else
#define UNITS_API __declspec(dllimport)
#endif
#else
#define UNITS_API __attribute__((visibility("default")))
#endif

/**
 * @brief 错误码枚举类型定义
 *
 * 列出所有可能的错误码，用于标识函数执行结果状态
 */
typedef enum {
  UNITS_SUCCESS = 0,                ///< 操作成功
  UNITS_INVALID_HANDLE,             ///< 无效的句柄
  UNITS_INVALID_PARAM,              ///< 无效参数
  UNITS_DIMENSION_NOT_FOUND,        ///< 未找到维度
  UNITS_UNIT_NOT_FOUND,             ///< 未找到单位
  UNITS_CONVERSION_FAILED,          ///< 转换失败
  UNITS_CUSTOM_CONV_EXISTS,         ///< 自定义转换已存在
  UNITS_FILE_IO_ERROR,              ///< 文件IO错误
  UNITS_CONFIG_PARSE_ERROR,         ///< 配置解析错误
  UNITS_INVALID_UNIT,               ///< 无效单位
  UNITS_DEFINED_UNITS_PARSE_ERROR,  ///< 已定义单位解析错误
  UNITS_UNKNOWN_ERROR               ///< 未知错误
} UnitsErrorCode;

/**
 * @brief 单位系统句柄类型定义
 *
 * 用于表示单位系统的实例对象，是一个不透明指针
 */
typedef void *UnitsHandle;

/**
 * @brief 创建一个新的单位系统实例
 *
 * @param[out] handle 指向新创建的单位系统句柄的指针
 * @return 返回操作结果的错误码
 */
UNITS_API UnitsErrorCode units_create(UnitsHandle *handle);

/**
 * @brief 销毁一个已有的单位系统实例
 *
 * @param[in] handle 要销毁的单位系统句柄
 * @return 返回操作结果的错误码
 */
UNITS_API UnitsErrorCode units_destroy(UnitsHandle handle);

/**
 * @brief 将字符串形式的测量值转换为目标单位
 *
 * @param[in] handle 单位系统句柄
 * @param[in] measurement 输入的测量值（如 "10 meters"）
 * @param[in] to 目标单位名称
 * @param[out] result 转换后的数值结果
 * @return 返回操作结果的错误码
 */
UNITS_API UnitsErrorCode units_convert_measurement(UnitsHandle handle,
                                                   const char *measurement,
                                                   const char *to,
                                                   double *result);

/**
 * @brief 数值单位转换接口
 *
 * @param[in] handle 单位系统句柄
 * @param[in] value 待转换的数值
 * @param[in] from 源单位名称
 * @param[in] to 目标单位名称
 * @param[out] result 转换后的数值结果
 * @return 返回操作结果的错误码
 */
UNITS_API UnitsErrorCode units_convert(UnitsHandle handle, double value,
                                       const char *from, const char *to,
                                       double *result);

/**
 * @brief 将数值从指定维度转换为基本单位
 *
 * @param[in] handle 单位系统句柄
 * @param[in] value 待转换的数值
 * @param[in] dimension 维度名称
 * @param[out] result 转换后的数值结果
 * @return 返回操作结果的错误码
 */
UNITS_API UnitsErrorCode units_convert_to_base(UnitsHandle handle, double value,
                                               const char *dimension,
                                               double *result);

/**
 * @brief 将数值从基本单位转换为指定维度的单位
 *
 * @param[in] handle 单位系统句柄
 * @param[in] value 待转换的数值
 * @param[in] dimension 维度名称
 * @param[out] result 转换后的数值结果
 * @return 返回操作结果的错误码
 */
UNITS_API UnitsErrorCode units_convert_from_base(UnitsHandle handle,
                                                 double value,
                                                 const char *dimension,
                                                 double *result);

/**
 * @brief 设置某个维度的基本单位
 *
 * @param[in] handle 单位系统句柄
 * @param[in] dimension 维度名称
 * @param[in] unit 单位名称
 * @return 返回操作结果的错误码
 */
UNITS_API UnitsErrorCode units_set_base_unit(UnitsHandle handle,
                                             const char *dimension,
                                             const char *unit);

/**
 * @brief 设置某个维度的当前使用单位
 *
 * @param[in] handle 单位系统句柄
 * @param[in] dimension 维度名称
 * @param[in] unit 单位名称
 * @return 返回操作结果的错误码
 */
UNITS_API UnitsErrorCode units_set_current_unit(UnitsHandle handle,
                                                const char *dimension,
                                                const char *unit);

/**
 * @brief 获取某个维度的基本单位名称
 *
 * @param[in] handle 单位系统句柄
 * @param[in] dimension 维度名称
 * @param[out] buffer 存储结果的缓冲区
 * @param[in] buf_size 缓冲区大小
 * @return 返回操作结果的错误码
 */
UNITS_API UnitsErrorCode units_get_base_unit(UnitsHandle handle,
                                             const char *dimension,
                                             char *buffer,
                                             unsigned int buf_size);

/**
 * @brief 获取某个维度的当前使用单位名称
 *
 * @param[in] handle 单位系统句柄
 * @param[in] dimension 维度名称
 * @param[out] buffer 存储结果的缓冲区
 * @param[in] buf_size 缓冲区大小
 * @return 返回操作结果的错误码
 */
UNITS_API UnitsErrorCode units_get_current_unit(UnitsHandle handle,
                                                const char *dimension,
                                                char *buffer,
                                                unsigned int buf_size);

/**
 * @brief 注册一个自定义单位定义
 *
 * @param[in] handle 单位系统句柄
 * @param[in] name 单位名称
 * @param[in] definition 单位定义表达式
 * @return 返回操作结果的错误码
 */
UNITS_API UnitsErrorCode units_register_defined_unit(UnitsHandle handle,
                                                     const char *name,
                                                     const char *definition);

/**
 * @brief 日志回调函数类型定义
 *
 * @param[in] level 日志级别（如 "info", "error" 等）
 * @param[in] message 日志消息内容
 */
typedef void (*UnitsLogCallback)(const char *level, const char *message);

/**
 * @brief 设置日志回调函数
 *
 * @param[in] handle 单位系统句柄
 * @param[in] logger 日志回调函数指针
 * @return 返回操作结果的错误码
 */
UNITS_API UnitsErrorCode units_set_logger(UnitsHandle handle,
                                          UnitsLogCallback logger);

/**
 * @brief 加载配置文件
 *
 * @param[in] handle 单位系统句柄
 * @param[in] config_file 配置文件路径
 * @return 返回操作结果的错误码
 */
UNITS_API UnitsErrorCode units_load_config_file(UnitsHandle handle,
                                                const char *config_file);

/**
 * @brief 保存配置到文件
 *
 * @param[in] handle 单位系统句柄
 * @param[in] config_file 配置文件路径
 * @return 返回操作结果的错误码
 */
UNITS_API UnitsErrorCode units_save_config_file(UnitsHandle handle,
                                                const char *config_file);

/**
 * @brief 从文件加载预定义单位
 *
 * @param[in] handle 单位系统句柄
 * @param[in] file 文件路径
 * @return 返回操作结果的错误码
 */
UNITS_API UnitsErrorCode units_load_defined_units_from_file(UnitsHandle handle,
                                                            const char *file);

/**
 * @brief 获取错误码对应的描述字符串
 *
 * @param[in] code 错误码
 * @return 对应的错误信息字符串
 */
UNITS_API const char *units_error_string(UnitsErrorCode code);

/**
 * @brief 测试单位系统功能
 *
 * 用于内部测试目的，验证单位系统是否正常工作
 */
UNITS_API void test_unit_system();

#ifdef __cplusplus
}
#endif

#endif  // LIB_INCLUDE_UNITS_C_H_